package cn.xlbweb.cli.service.impl;

import cn.xlbweb.cli.common.constant.PermissionConstants;
import cn.xlbweb.cli.common.constant.UserConsts;
import cn.xlbweb.cli.config.CliProperties;
import cn.xlbweb.cli.mapper.PermissionMapper;
import cn.xlbweb.cli.mapper.RoleMapper;
import cn.xlbweb.cli.mapper.UserMapper;
import cn.xlbweb.cli.mapper.UserRoleMapper;
import cn.xlbweb.cli.model.*;
import cn.xlbweb.cli.common.ServerResponse;
import cn.xlbweb.cli.common.TableResponse;
import cn.xlbweb.cli.pojo.dto.InsertUserDTO;
import cn.xlbweb.cli.pojo.dto.UpdateUserDTO;
import cn.xlbweb.cli.pojo.dto.ListUserDTO;
import cn.xlbweb.cli.pojo.vo.*;
import cn.xlbweb.cli.service.IUserService;
import cn.xlbweb.cli.util.CliUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: bobi
 * @date: 2019-09-15 14:15
 * @description:
 */
@Service
@Slf4j
public class UserServiceImpl implements IUserService {

    @Autowired
    private CliProperties cliProperties;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public Object xxx() {
        List<Permission> permissionList = permissionMapper.selectByExample(null);
        return listCurrentUserMenu(permissionList, PermissionConstants.ROOT_ID);
    }

    @Override
    public ServerResponse getCurrentUser() {
        // 基本信息
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        GetCurrentUserVO vo = new GetCurrentUserVO();
        CliUtils.copyProperties(user, vo);
        // 菜单
        List<Permission> permissionList = permissionMapper.selectByExample(null);
        vo.setMenus(listCurrentUserMenu(permissionList, PermissionConstants.ROOT_ID));
        return ServerResponse.success("查询成功", vo);
    }

    @Override
    public User getUserByUsername(String username) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(username);
        List<User> userList = userMapper.selectByExample(userExample);
        return !CollectionUtils.isEmpty(userList) ? userList.get(0) : null;
    }

    @Override
    public TableResponse listUser(ListUserDTO usersListDTO) {
        log.info("listUser() start...");
        // 构建查询条件
        UserExample userExample = new UserExample();
        if (StringUtils.isNotBlank(usersListDTO.getUsername())) {
            userExample.createCriteria().andUsernameLike("%" + usersListDTO.getUsername() + "%");
        }
        if (StringUtils.isNotBlank(usersListDTO.getEmail())) {
            userExample.createCriteria().andEmailLike("%" + usersListDTO.getEmail() + "%");
        }

        // 构建分页
        PageHelper.startPage(usersListDTO.getCurrentPage(), usersListDTO.getPageSize());
        List<User> users = userMapper.selectByExample(userExample);
        PageInfo<User> userPageInfo = new PageInfo<>(users);

        // 构建Vo
        List<ListUserVO> vos = new ArrayList<>();
        users.forEach(user -> {
            ListUserVO vo = new ListUserVO();
            CliUtils.copyProperties(user, vo);
            // 查询该用户的所有角色
            List<String> roleNames = new ArrayList<>();
            // 超级管理员
            if (StringUtils.equals(user.getUsername(), UserConsts.ADMIN_USERNAME)) {
                List<Role> roles = roleMapper.selectByExample(null);
                roles.forEach(item -> {
                    roleNames.add(item.getName());
                });
            } else { // 普通用户
                UserRoleExample userRoleExample = new UserRoleExample();
                userRoleExample.createCriteria().andUserIdEqualTo(user.getId());
                List<UserRole> userRoleList = userRoleMapper.selectByExample(userRoleExample);
                for (UserRole userRole : userRoleList) {
                    Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                    roleNames.add(role.getName());
                }
            }
            vo.setRoleNames(roleNames);
            vos.add(vo);
        });
        log.info("listUser() end...");
        return TableResponse.success(userPageInfo.getTotal(), vos);
    }

    @Override
    public ServerResponse getUser(Integer userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (user != null) {
            // 查询角色
            UserRoleExample userRoleExample = new UserRoleExample();
            List<Integer> roleIds = new ArrayList<>();
            // 超级管理员
            if (StringUtils.equals(user.getUsername(), UserConsts.ADMIN_USERNAME)) {
                List<Role> roles = roleMapper.selectByExample(null);
                roles.forEach(item -> roleIds.add(item.getId()));
            } else {
                userRoleExample.createCriteria().andUserIdEqualTo(userId);
                List<UserRole> userRoles = userRoleMapper.selectByExample(userRoleExample);
                userRoles.forEach(item -> {
                    Role role = roleMapper.selectByPrimaryKey(item.getRoleId());
                    roleIds.add(role.getId());
                });
            }
            // 构造VO
            GetUserVO vo = new GetUserVO();
            CliUtils.copyProperties(user, vo);
            vo.setRoleIds(roleIds);
            return ServerResponse.success("查询成功", vo);
        }
        return ServerResponse.error("用户不存在");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServerResponse insertUser(InsertUserDTO insertUserDTO) {
        // 判断用户名是否已经存在
        if (StringUtils.isNotBlank(insertUserDTO.getUsername())) {
            return ServerResponse.error("用户名已存在");
        }
        // 加密密码
        String encryptionPassword = new SimpleHash(cliProperties.getAlgorithmName(), insertUserDTO.getPassword(), ByteSource.Util.bytes(insertUserDTO.getUsername()), cliProperties.getHashIterations()).toHex();
        insertUserDTO.setPassword(encryptionPassword);
        // 插入用户
        User user = new User();
        CliUtils.copyProperties(insertUserDTO, user);
        int count = userMapper.insertSelective(user);
        // 插入角色
        insertUserRole(user, insertUserDTO.getRoleIds());
        if (count > 0) {
            return ServerResponse.success("添加成功");
        }
        return ServerResponse.error("插入失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServerResponse updateUser(UpdateUserDTO updateUserDTO) {
        // 判断用户名是否已经存在
        User dbUser = userMapper.selectByPrimaryKey(updateUserDTO.getId());
        if (!StringUtils.equals(updateUserDTO.getUsername(), dbUser.getUsername()) && StringUtils.isNotBlank(updateUserDTO.getUsername())) {
            return ServerResponse.error("用户名已存在");
        }
        // 删除旧角色
        deleteUserRole(String.valueOf(updateUserDTO.getId()));
        // 更新用户
        CliUtils.copyProperties(updateUserDTO, dbUser);
        int count = userMapper.updateByPrimaryKeySelective(dbUser);
        // 插入新角色
        insertUserRole(dbUser, updateUserDTO.getRoleIds());
        if (count > 0) {
            return ServerResponse.success("更新成功");
        }
        return ServerResponse.error("更新失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServerResponse deleteUser(String ids) {
        // 删除该用户所拥有的全部角色
        deleteUserRole(ids);
        // 构建删除条件
        UserExample userExample = new UserExample();
        userExample.createCriteria().andIdIn(CliUtils.getIdList(ids));
        // 删除用户
        int count = userMapper.deleteByExample(userExample);
        if (count > 0) {
            return ServerResponse.success("删除成功");
        }
        return ServerResponse.error("删除失败");
    }

    private List<ListCurrentUserMenuVO> listCurrentUserMenu(List<Permission> permissionList, Integer parentId) {
        List<ListCurrentUserMenuVO> vos = new ArrayList<>();
        for (Permission permission : permissionList) {
            if (permission.getPid().equals(parentId) && !permission.getType().equals(PermissionConstants.TYPE_BUTTON)) {
                ListCurrentUserMenuVO vo = new ListCurrentUserMenuVO();
                CliUtils.copyProperties(permission, vo);
                Map<String, String> meta = new HashMap<>();
                meta.put("title", permission.getName());
                meta.put("icon", permission.getIcon());
                vo.setMeta(meta);
                vos.add(vo);
            }
        }
        for (ListCurrentUserMenuVO vo : vos) {
            vo.setChildren(listCurrentUserMenu(permissionList, vo.getId()));
        }
        return vos;
    }

    private void insertUserRole(User user, String roleIds) {
        for (Integer roleId : CliUtils.getIdList(roleIds)) {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(roleId);
            Role role = roleMapper.selectByPrimaryKey(roleId);
            userRole.setRemarks(user.getUsername() + "-" + role.getName());
            userRoleMapper.insertSelective(userRole);
        }
    }

    private void deleteUserRole(String userIds) {
        List<Integer> idList = CliUtils.getIdList(userIds);
        UserRoleExample userRoleExample = new UserRoleExample();
        userRoleExample.createCriteria().andUserIdIn(idList);
        int count = userRoleMapper.deleteByExample(userRoleExample);
        if (count > 0) {
            log.info("成功删除{}条用户的角色信息", count);
        }
    }
}
